package cs342.project1.mathNotebook.expressions;

import cs342.project1.mathNotebook.expressions.exceptions.UncapturedVariableException;

public class ToStringVisitor implements Visitor {

    public String visit(Expr exp) {
	throw new IllegalArgumentException(
		"Cannot evaluate an instance of the abstract class Expression");
    }

    @Override
    public String visit(AddExpr exp) throws UncapturedVariableException {
	String lhs = (String) exp.lhs.accept(this);
	String rhs = (String) exp.rhs.accept(this);
	return "(" + lhs + "+" + rhs + ")";
    }

    @Override
    public String visit(SubExpr exp) throws UncapturedVariableException {
	String lhs = (String) exp.lhs.accept(this);
	String rhs = (String) exp.rhs.accept(this);
	return "(" + lhs + "-" + rhs + ")";
    }

    @Override
    public String visit(MultExpr exp) throws UncapturedVariableException {
	String lhs = (String) exp.lhs.accept(this);
	String rhs = (String) exp.rhs.accept(this);
	return "(" + lhs + "*" + rhs + ")";
    }

    @Override
    public String visit(DivExpr exp) throws UncapturedVariableException {
	String lhs = (String) exp.lhs.accept(this);
	String rhs = (String) exp.rhs.accept(this);
	return "(" + lhs + "/" + rhs + ")";
    }

    @Override
    public String visit(NegExpr exp) throws UncapturedVariableException {
	return "(-" + exp.argument.accept(this) + ")";
    }

    @Override
    public String visit(SinExpr exp) throws UncapturedVariableException {
	return "Sin(" + (String) exp.argument.accept(this) + ")";
    }

    @Override
    public String visit(CosExpr exp) throws UncapturedVariableException {
	return "Cos(" + (String) exp.argument.accept(this) + ")";
    }

    @Override
    public String visit(TanExpr exp) throws UncapturedVariableException {
	return "Tan(" + (String) exp.argument.accept(this) + ")";
    }

    @Override
    public String visit(VarExpr exp) {
	return exp.name;
    }

    @Override
    public String visit(LiteralExpr exp) {
	return "" + exp.value;
    }

    @Override
    public Object visit(PowExpr exp) {
	return null;
    }
}